package com.mutual.reins.trial.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mutual.base.exception.BusinessException;
import com.mutual.redis.service.RedisService;
import com.mutual.reins.config.entity.FhPriority;
import com.mutual.reins.config.entity.FhTreaty;
import com.mutual.reins.config.service.IFhPriorityService;
import com.mutual.reins.config.service.IFhTreatyService;
import com.mutual.reins.danger.entity.PrptDangerCoins;
import com.mutual.reins.danger.entity.PrptDangerUnit;
import com.mutual.reins.danger.service.IPrptDangerCoinsService;
import com.mutual.reins.danger.service.IPrptDangerUnitService;
import com.mutual.reins.interf.entity.ReinsPolicyUnit;
import com.mutual.reins.interf.service.IReinsPolicyUnitService;
import com.mutual.reins.trial.entity.PrptTrialShareDto;
import com.mutual.reins.trial.entity.TrialTreaty;
import com.mutual.reins.trial.service.IGeneratePrptReinsTrialService;
import com.mutual.reins.trial.service.ITrialTreatyService;
import com.mutual.reins.utils.constraint.ReinsConst;
import com.mutual.reins.utils.constraint.UserExceptionEnum;
import lombok.AllArgsConstructor;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * 实现投保单试算接口
 * @author pc
 * @date 2021-04-28
 */
public class GeneratePrptReinsTrialServiceImpl implements IGeneratePrptReinsTrialService {
    @Autowired
    private RedisService redisService;
    @Autowired
    private IPrptDangerUnitService iPrptDangerUnitService;
    @Autowired
    private IReinsPolicyUnitService iReinsPolicyUnitService;
    @Autowired
    private IPrptDangerCoinsService iPrptDangerCoinsService;
    @Autowired
    private IFhPriorityService iFhPriorityService;
    @Autowired
    private ITrialTreatyService iTrialTreatyService;
    @Autowired
    private IFhTreatyService iFhTreatyService;
    /**
     * 针对每个投保单危险单位进行分保试算
     *
     * @param proposalNo 投保单号集合
     */
    @Override
    public void simulateRePolicyByDangerNo(List<String> proposalNo) {
        if(!proposalNo.isEmpty() && ObjectUtil.isNotNull(proposalNo)){
            QueryWrapper queryWrapper  = new QueryWrapper<>();
            queryWrapper.in("PROPOSALNO",proposalNo);
            Map<String, PrptDangerUnit> prptDangerUnitMap = iPrptDangerUnitService.selectPrptDangerUnitMap(queryWrapper);
            Map<String,List<PrptDangerCoins>> prptDangerCoinsMap = iPrptDangerCoinsService.selectPrptDangerCoinsMap(queryWrapper);
            Map<String, ReinsPolicyUnit> reinsPolicyUnitMap = iReinsPolicyUnitService.selectReinsPolicyUnitMap(queryWrapper);
            Map<String, List<TrialTreaty>> trialTreatyMap = iTrialTreatyService.selectTrialTreatyMap(queryWrapper);
            Map<String, FhTreaty> fhTreatyMap = iFhTreatyService.getFhTreatyMap();
            for(String key:prptDangerUnitMap.keySet()){
                PrptDangerUnit prptDangerUnit = prptDangerUnitMap.get(key);
                ReinsPolicyUnit reinsPolicyUnit = reinsPolicyUnitMap.get(prptDangerUnit.getProposalNo());
                List<PrptDangerCoins> prptDangerCoinsList = prptDangerCoinsMap.get(key);
                List<TrialTreaty> trialTreatyList = trialTreatyMap.get(prptDangerUnit.getProposalNo()+"-"+prptDangerUnit.getDangerNo());
                //获取该prptDangerUnit对象计算保额保费等信息
                PrptTrialShareDto prptTrialShareDto = this.genPrptTrialShareDto(prptDangerUnit,prptDangerCoinsList);
                // 先删除投保单原有分保试算结果
                //this.deleteReinsTrialInfo(certiNo, dangerNo);
                // 获取分保方式的优先级
                this.getPriority(reinsPolicyUnit, prptDangerUnit,prptTrialShareDto,trialTreatyList);
                // 计算附加自留
               // this.appendRetention(reinsPolicyUnitDto, prpTdangerUnitDto);
                // 添加调差
                //this.adjustTrialResult(prpTdangerUnitDto);
            }
        }else{
            throw new BusinessException(UserExceptionEnum.REINS_PRPTTRIAL_NOT_EXISTS.getCode(),UserExceptionEnum.REINS_PRPTTRIAL_NOT_EXISTS.getMessage());
        }
    }

    /**
     * 获取分保方式的优先级
     * @param reinsPolicyUnit 投保单接口表数据
     * @param prptDangerUnit 危险单位Unit
     * @param prptTrialShareDto 投保单计算基本数据
     */
    private void getPriority(ReinsPolicyUnit reinsPolicyUnit, PrptDangerUnit prptDangerUnit, PrptTrialShareDto prptTrialShareDto,List<TrialTreaty> trialTreatyList) {

        String strUwYear = String.valueOf(reinsPolicyUnit.getStartDate().getYear());
        String startDate = "";
        if (iFhPriorityService.ifTreatyValid(strUwYear)) {
            // 如果没有合约配置，则取当年合约配置
            strUwYear = String.valueOf(LocalDate.now().getYear());
            startDate = LocalDate.now().getYear() + "-"
                    + reinsPolicyUnit.getStartDate().getMonth()
                    + "-" + reinsPolicyUnit.getStartDate().getDayOfMonth();
        }

        // 按业务年度、优先级顺序获取合约信息
        List<FhPriority> fhPriorityList = iFhPriorityService.selectUwYearInFhTreaty(strUwYear,startDate);
        //匹配
        if (fhPriorityList.isEmpty() && ObjectUtil.isNull(fhPriorityList)) {
            throw new BusinessException("请设置" + strUwYear + "的分保合约优先级顺序信息");
        }
        // 判断试算合约
        String ziheflag="";
        if(trialTreatyList.size()==1){
            for(TrialTreaty trialTreaty:trialTreatyList){
                if(ReinsConst.TREATY_OUT_SURPLUS.equals(trialTreaty.getFlag())){
                    ziheflag="0";
                }
            }
        }
//        for (FhPriority  fhPriority: fhPriorityList) {
//            TrialTreatyDto trialTreatyDto=new TrialTreatyDto();
//
//            fhTreatyDto = dbFhTreaty.findByPrimaryKey(fhPriorityDto
//                    .getTreatyNo());
//            if (fhTreatyDto == null) {
//                throw new Exception("没有相应的合约信息，请先设置"
//                        + fhPriorityDto.getTreatyNo() + "相应的合约信息");
//            }
//
//            // 合约编码
//            treatyNo = fhTreatyDto.getTreatyNo();
//            // modify begin 20060608 by lihua 转分入业务在分保试算时不进行合约分出
//            treatyType = fhTreatyDto.getTreatyType();
//            //add by huwenda 匹配是否为所选合约
//            if(treatyCol.size()>0&&!"0".equals(ziheflag)){
//                if("21".equals(treatyType)||"31".equals(treatyType)){
//                    trialTreatyDto=dbTrialTreaty.findByPrimaryKey(prpTdangerUnitDto.getProposalNo(), treatyNo,prpTdangerUnitDto.getDangerNo());
//                    if(trialTreatyDto==null){
//                        continue;
//                    }
//                }
//
//            }
//            boolean reinsCeded = true;
//
//            /** 分入业务不进法定分出，直接进自留 */
//            //if ("1".equals(prpTdangerUnitDto.getBusinessFlag())
//            //		&& "11".equals(treatyType)) {
//            //	treatyType = "81";
//            //}
//
//            if (prpTdangerUnitDto.getBusinessFlag().equals("1")) {
//                ReinsPolicyCededDto reinsPolicyCededDto = new ReinsPolicyCededDto();
//                DBReinsPolicyCeded dbReinsPolicyCeded = new DBReinsPolicyCeded(dbManager);
//                reinsPolicyCededDto = dbReinsPolicyCeded.findByPrimaryKey(prpTdangerUnitDto.getProposalNo());
//                if(reinsPolicyCededDto != null) {
//                    String reinsCededType =reinsPolicyCededDto .getCededType();// 分入类型 0:直接分入 1:转分分入
//                    if(reinsCededType.equals("1")) {
//                        reinsCeded = false;
//                    } if(reinsCeded) {
//                        treatyType = fhTreatyDto.getTreatyType();
//                    } else{// 转分入业务在分保试算时不进行合约分出
//                        treatyType = "81";
//                    }
//                }
//            }
//
//            // modify end 20060608 by lihua 转分入业务在分保试算时不进行合约分出
//            switch (Integer.parseInt(treatyType)) {
//                case 11:
//                    // 法定分保
//                    this.legalShare(prpTdangerUnitDto, treatyNo, treatyType,
//                            dbManager);
//                    break;
//                case 21:
//                    // 溢额分保
//                    this.OverShare(reinsPolicyUnitDto, prpTdangerUnitDto, treatyNo,
//                            treatyType, dbManager);
//                    break;
//                case 31:
//                    // 成数分保
//                    // modify begin by zhaijq 20060511 1903险种按照每座限额进行分保处理
//                    // this.QuotaShare(prpTmainDto, prpTdangerUnitDto, treatyNo,
//                    // treatyType, dbManager);
//                    this.QuotaShare(reinsPolicyUnitDto, prpTdangerUnitDto, treatyNo,
//                            treatyType, dbManager);
//                    // modify end by zhaijq 20060511
//                    break;
//                case 41:
//                    // 预约分保
//                    this.openCover(reinsPolicyUnitDto, prpTdangerUnitDto, treatyNo,
//                            treatyType, dbManager);
//                    break;
//                case 91:
//                    // 普通临分
//                    this.Facultative(reinsPolicyUnitDto, prpTdangerUnitDto, treatyNo,
//                            treatyType, dbManager);
//                    break;
//                case 92:
//                    // 特约临分
//                    this.SpecialShare(reinsPolicyUnitDto, prpTdangerUnitDto, treatyNo,
//                            treatyType, dbManager);
//                    break;
//                case 61:
//                    // 协议分保
//                    this.AgreementShare(prpTdangerUnitDto, treatyNo, treatyType,
//                            dbManager);
//                    break;
//                case 51:
//                    // 成数溢额混合合约分保
//                    this.CommixShare(reinsPolicyUnitDto, prpTdangerUnitDto, treatyNo,
//                            treatyType, dbManager);
//                    break;
//                case 81:
//                    // 合约自留信息的保存
//                    this.treatyRetention(reinsPolicyUnitDto, prpTdangerUnitDto, dbManager);
//                    break;
//            }
//        }

    }

    /**
     * 获取该prptDangerUnit对象计算保额保费等信息
     * @param prptDangerUnit 危险单位信息
     * @param prptDangerCoinsList 危险单位共保信息
     * @return 投保单计算基本数据
     */
    private PrptTrialShareDto genPrptTrialShareDto(PrptDangerUnit prptDangerUnit, List<PrptDangerCoins> prptDangerCoinsList) {
        double dblBaseAmount = 0D;
        double dblBasePremium = 0D;
        double disFee = 0D;
        double dblBaseShare = 0D;
        PrptTrialShareDto prptTrialShareDto= new PrptTrialShareDto();
        if(ObjectUtil.isNotNull(prptDangerCoinsList) && !prptDangerCoinsList.isEmpty()){
            for (PrptDangerCoins prptDangerCoins:prptDangerCoinsList){
                if (ReinsConst.COINSTYPE_ME.equals(prptDangerCoins.getCoinsType()) || ReinsConst.COINSTYPE_OTH_IN.equals(prptDangerCoins.getCoinsType())) {
                    dblBaseAmount = dblBaseAmount + prptDangerCoins.getCoinsAmount().doubleValue();
                    dblBasePremium = dblBasePremium+ prptDangerCoins.getCoinsPremium().doubleValue() - prptDangerCoins.getMiddleCostFee().doubleValue();
                    disFee = disFee + prptDangerCoins.getMiddleCostFee().doubleValue();
                    dblBaseShare = dblBaseShare + prptDangerCoins.getCoinsRate().doubleValue();
                }
            }
        }else{
            // 我司份额初始化问题
            dblBaseShare = 100;
            // 危险单位的总保额
            dblBaseAmount = prptDangerUnit.getAmount().doubleValue();
            // 危险单位的总保费
            dblBasePremium = prptDangerUnit.getPremium().doubleValue();
            // 危险单位的中间成本
            disFee = prptDangerUnit.getDisFee().doubleValue();
            // 总保费=总保费-中间成本
            dblBasePremium = dblBasePremium - disFee;
        }
        // 危险单位的待分保额
        prptTrialShareDto.setMDblReTenAmount(dblBaseAmount);
        // 危险单位的待分保费
        prptTrialShareDto.setMDblReTenPremium(dblBasePremium);
        prptTrialShareDto.setSerialNoShare(1);
        prptTrialShareDto.setSerialNoTrial(1);
        return prptTrialShareDto;
    }
}
